package com.mofum.msdom.excel.annotation.parser.impl;

import com.mofum.msdom.excel.annotation.ATHeaderColumn;
import com.mofum.msdom.excel.annotation.ATStyle;
import com.mofum.msdom.excel.annotation.parser.AnnotationParser;
import com.mofum.msdom.excel.metadata.MPHeaderColumn;
import com.mofum.msdom.excel.metadata.MPStyle;
import com.mofum.msdom.excel.utils.ReflectUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 头部列解析器
 *
 * @author 1615690513@qq.com
 * @since 2018/11/28 0028 15:00
 */
public class ATHeaderColumnParser<T> implements AnnotationParser<T, MPHeaderColumn> {

    public Map<Field, MPHeaderColumn> parseField(T o) {

        Map<Field, MPHeaderColumn> map = new HashMap<Field, MPHeaderColumn>();

        Field[] fields = ReflectUtils.convertToClass(o).getDeclaredFields();

        for (Field field : fields) {

            if (field.isAnnotationPresent(ATHeaderColumn.class)) {

                ATHeaderColumn atHeaderColumn = field.getAnnotation(ATHeaderColumn.class);

                map.put(field, parse(atHeaderColumn));

            }

        }

        return map;
    }

    public Map<Type, MPHeaderColumn> parseType(T o) {

        Map<Type, MPHeaderColumn> map = new HashMap<Type, MPHeaderColumn>();

        Class<T> clazz = ReflectUtils.convertToClass(o);

        if (clazz.isAnnotationPresent(ATHeaderColumn.class)) {

            ATHeaderColumn atHeaderColumn = clazz.getAnnotation(ATHeaderColumn.class);

            map.put(clazz, parse(atHeaderColumn));

        }

        return map;
    }

    public Map<Method, MPHeaderColumn> parseMethod(T o) {

        Map<Method, MPHeaderColumn> map = new HashMap<Method, MPHeaderColumn>();

        Method[] methods = ReflectUtils.convertToClass(o).getDeclaredMethods();

        for (Method method : methods) {

            if (method.isAnnotationPresent(ATHeaderColumn.class)) {

                ATHeaderColumn atHeaderColumn = method.getAnnotation(ATHeaderColumn.class);

                map.put(method, parse(atHeaderColumn));

            }

        }

        return map;
    }

    public Map<Method, List<MPHeaderColumn>> parseParams(T o) {

        Map<Method, List<MPHeaderColumn>> map = new HashMap<Method, List<MPHeaderColumn>>();

        Method[] methods = ReflectUtils.convertToClass(o).getMethods();

        for (Method method : methods) {

            List<MPHeaderColumn> list = new ArrayList<MPHeaderColumn>();

            Annotation[][] parameterAnnotations = method.getParameterAnnotations();

            for (Annotation[] parameterAnnotation : parameterAnnotations) {
                for (Annotation annotation : parameterAnnotation) {
                    if (annotation instanceof ATHeaderColumn) {
                        ATHeaderColumn atHeaderColumn = (ATHeaderColumn) annotation;
                        list.add(parse(atHeaderColumn));
                    }
                }
            }

            map.put(method, list);
        }

        return map;
    }


    public MPHeaderColumn parse(ATHeaderColumn atHeaderColumn) {
        MPHeaderColumn mpHeaderColumn = new MPHeaderColumn();

        mpHeaderColumn.setHeight(atHeaderColumn.height());
        mpHeaderColumn.setIndex(atHeaderColumn.index());
        mpHeaderColumn.setValue(atHeaderColumn.value());
        mpHeaderColumn.setWidth(atHeaderColumn.width());

        //样式
        ATStyleParser<MPStyle> parser = new ATStyleParser();
        List<MPStyle> list = new ArrayList<MPStyle>();
        for (ATStyle atStyle : atHeaderColumn.styles()) {
            list.add(parser.parse(atStyle));
        }
        mpHeaderColumn.setStyles(list.toArray(new MPStyle[]{}));
        return mpHeaderColumn;
    }
}
